package codeCreate.restfulAPICreate.util.annotation.resolve;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;

import codeCreate.domain.Country;
import codeCreate.restfulAPICreate.domain.ApplyMessageCodeRequest;
import codeCreate.restfulAPICreate.util.annotation.constant.Constants;
import codeCreate.restfulAPICreate.util.annotation.type.Column;

public class BeanAnnotationResolve {
    private static String name = "name";
    private static String is_null = "isNull";
    private static String field_name = "fieldName";
    private static String length = "length";
    private static String introduction = "introduction";
    private static String field_type = "fieldType";
    private static Class<?>[] baseReturnType = { Integer.class, Long.class, Float.class, Double.class, char.class,
            Short.class, Date.class, String.class };

    public static List<Map<String, Object>> resolve(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<Map<String, Object>> list = new ArrayList<>();
        for (Field field : fields) {
            Column column = field.getAnnotation(Column.class);
            if (column == null) {
                continue;
            }
            Map<String, Object> columnMap = new HashMap<>();
            Class<?> fieldClass = field.getType();
            if (Arrays.asList(baseReturnType).contains(fieldClass) || fieldClass.isPrimitive()) {
                columnMap.put(field_name, field.getName());
                columnMap.put(name, column.name());
                columnMap.put(is_null, Constants.LogicVariable.NO.equals(column.isNull()) ? "必填" : "可选");
                columnMap.put(introduction, column.introduction());
                columnMap.put(field_type, field.getType().getSimpleName());
                columnMap.put(length, column.length());
            } else if (fieldClass.isAssignableFrom(List.class)) {
                Type type = field.getGenericType();
                Class genaricClass = null;
                if (type instanceof ParameterizedType) {
                    ParameterizedType t = (ParameterizedType) (field.getGenericType());
                    genaricClass = (Class) t.getActualTypeArguments()[0];
                }
                // 只支持list中为自定义类的字段
                if (!genaricClass.isPrimitive() && !Arrays.asList(baseReturnType).contains(genaricClass)) {
                    List<Map<String, Object>> listMap = resolve(genaricClass);
                    columnMap.put(field.getName(), listMap);
                    columnMap.put(field_name, field.getName());
                    columnMap.put(name, column.name());
                    columnMap.put(is_null, Constants.LogicVariable.NO.equals(column.isNull()) ? "必填" : "可选");
                    columnMap.put(introduction, column.introduction());
                    columnMap.put(field_type, field.getType().getSimpleName());
                    columnMap.put(length, column.length());
                }
            } else if (!fieldClass.isAssignableFrom(Collection.class)) {
                List<Map<String, Object>> listMap = resolve(fieldClass);
                columnMap.put(field.getName(), listMap);
                columnMap.put(field_name, field.getName());
                columnMap.put(name, column.name());
                columnMap.put(is_null, Constants.LogicVariable.NO.equals(column.isNull()) ? "必填" : "可选");
                columnMap.put(introduction, column.introduction());
                columnMap.put(field_type, field.getType().getSimpleName());
                columnMap.put(length, column.length());
            }
            list.add(columnMap);
        }
        return list;
    }

    @SuppressWarnings("unchecked")
    public static List<String[]> resolveBeanMapList2Array(List<Map<String, Object>> mapList, List<String[]> resultList,
            String[] template) {
        if (resultList == null) {
            resultList = new ArrayList<>();
        }
        for (Map<String, Object> columnMap : mapList) {
            String[] columnInfo = new String[template.length];
            for (int i = 0; i < template.length; i++) {
                Object object = columnMap.get(template[i]);
                if (object instanceof Integer && ((Integer) object).intValue() == 0) {
                    columnInfo[i] = "";
                } else {
                    String info = String.valueOf(columnMap.get(template[i]));
                    columnInfo[i] = !StringUtils.isEmpty(info) ? info : "";
                }
            }
            resultList.add(columnInfo);
            String fieldName = (String) columnMap.get(field_name);
            if (columnMap.get(fieldName) instanceof List) {
                resolveBeanMapList2Array((List<Map<String, Object>>) columnMap.get(fieldName), resultList, template);
            }
        }
        return resultList;
    }

    public static void main(String[] args) {
        System.out.println(JSON.toJSONString(BeanAnnotationResolve.resolve(ApplyMessageCodeRequest.class)));
    }
}
